home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / Snippets / Toolbox / GiMeDaPalette w⁄Sound / GiMeDaPalette&Sound.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  17.8 KB  |  644 lines  |  [TEXT/MPS ]

  1. /*______________________________________________________*/
  2. /*                       Palette Demo                        */
  3. /*                          by                          */
  4. /*                  RICHARD P. COLLYER                  */
  5. /*              Developer Technical Support             */
  6. /*                 Apple Computer, Inc.                 */
  7. /*                       08/15/90                       */
  8. /*______________________________________________________*/
  9.  
  10. #include    <CType.h>
  11. #include    <Quickdraw.h>
  12. #include    <Windows.h>
  13. #include    <desk.h>
  14. #include    <dialogs.h>
  15. #include    <Events.h>
  16. #include     <GestaltEqu.h>
  17. #include    <Memory.h>
  18. #include    <Menus.h>
  19. #include    <OSEvents.h>
  20. #include    <Palette.h>
  21. #include    <SegLoad.h>
  22. #include    <Sound.h>
  23. #include    <Resources.h>
  24. #include    <ToolUtils.h>
  25. #include    <StdIO.h>
  26. #include    <QDOffscreen.h>
  27.  
  28. extern _DataInit();
  29.  
  30. #define pmInhibitG2        0x0100
  31. #define pmInhibitC2        0x0200
  32. #define pmInhibitG4        0x0400
  33. #define pmInhibitC4        0x0800
  34. #define pmInhibitG8        0x1000
  35. #define pmInhibitC8        0x2000
  36.  
  37. #define    TRUE            0xFF
  38. #define    FALSE            0
  39. #define Gestalttest        0xA1AD
  40. #define NoTrap            0xA89F
  41.  
  42. #define    appleID            128            
  43. #define    appleMenu        0
  44. #define    aboutMeCommand    1
  45.  
  46. #define    fileID            129
  47. #define    quitCommand     1
  48.  
  49. #define    PaletteID        130
  50. #define    CourCommand     1
  51. #define    TolCommand         2
  52. #define    ExpCommand         3
  53. #define    AniCommand         4
  54. #define    TolExpCommand     6
  55. #define    TolAniCommand     7
  56. #define    ExpAniCommand     8
  57. #define    TEACommand         10
  58.  
  59. #define    PictID            128
  60. #define    clutID            150
  61.  
  62. #define    aboutMeDLOG        128
  63. #define    okButton        1
  64. #define    authorItem        2
  65. #define    languageItem    3
  66. #define    numcolor        256
  67.  
  68. #define kDoubleBufferSize    0x1000
  69.  
  70. struct LocalVars {
  71.     long    bytesTotal;
  72.     long    bytesCopied;
  73.     Ptr        dataPtr;
  74. };
  75.  
  76. typedef struct LocalVars LocalVars;
  77. typedef LocalVars *LocalVarsPtr;
  78.  
  79. Rect                    TotalRect, minRect, WinMinusScroll, InitWindowSize;
  80. WindowPtr                myWindow;
  81. CTabHandle                mycolors;
  82. PaletteHandle            srcPalette;
  83. Boolean                    DoneFlag;
  84. MenuHandle                mymenu1, mymenu2, mymenu0;
  85. PicHandle                ThePict;
  86. GWorldPtr                offscreenGWorld;
  87. SndDoubleBufferHeader    doubleHeader;
  88. SndDoubleBufferPtr        doubleBuffer;
  89. SCStatus                Stats;
  90. SndChannelPtr            chan;
  91. SoundHeaderPtr            Head;
  92. Handle                    SoundData;
  93. LocalVars                myVars;
  94.  
  95. pascal void MyDoubleBackProc (SndChannelPtr channel,
  96.                                             SndDoubleBufferPtr doubleBufferPtr);
  97.  
  98. /*______________________________________________________*/
  99. /*              Sound Double Back Proc                  */
  100. /*______________________________________________________*/
  101. pascal void MyDoubleBackProc (SndChannelPtr chan,SndDoubleBufferPtr doubleBuffer)
  102. {
  103. LocalVarsPtr    myVarsPtr;
  104. long            bytesToCopy;
  105.  
  106. myVarsPtr = (LocalVarsPtr) doubleBuffer->dbUserInfo[0];
  107. bytesToCopy = myVarsPtr->bytesTotal - myVarsPtr->bytesCopied;
  108.  
  109. if (bytesToCopy > kDoubleBufferSize)
  110.     bytesToCopy = kDoubleBufferSize;
  111.     
  112. BlockMove (myVarsPtr->dataPtr, &doubleBuffer->dbSoundData[0], bytesToCopy);
  113.  
  114. doubleBuffer->dbNumFrames = bytesToCopy;
  115. doubleBuffer->dbFlags = (doubleBuffer->dbFlags) | dbBufferReady;
  116.  
  117. myVarsPtr->dataPtr = (Ptr) ((myVarsPtr->dataPtr) + bytesToCopy);
  118. myVarsPtr->bytesCopied = myVarsPtr->bytesCopied + bytesToCopy;
  119.  
  120. if (myVarsPtr->bytesCopied == myVarsPtr->bytesTotal) {
  121.     doubleBuffer->dbFlags = (doubleBuffer->dbFlags) | dbLastBuffer;
  122.     }
  123.     
  124. return;
  125. }
  126.  
  127. /*______________________________________________________*/
  128. /*                Check Correct Menu                    */
  129. /*______________________________________________________*/
  130. void CheckMenu(int whichMenu)
  131. /* This procedure checks and unchecks the appropriate menus */
  132. {
  133.             CheckItem(mymenu2,CourCommand,FALSE);
  134.             CheckItem(mymenu2,TolCommand,FALSE);
  135.             CheckItem(mymenu2,ExpCommand,FALSE);
  136.             CheckItem(mymenu2,AniCommand,FALSE);
  137.             CheckItem(mymenu2,TolExpCommand,FALSE);
  138.             CheckItem(mymenu2,TolAniCommand,FALSE);
  139.             CheckItem(mymenu2,ExpAniCommand,FALSE);
  140.             CheckItem(mymenu2,TEACommand,FALSE);
  141.     switch (whichMenu) {
  142.         case CourCommand:
  143.             CheckItem(mymenu2,CourCommand,TRUE);
  144.             break;
  145.         case TolCommand:
  146.             CheckItem(mymenu2,TolCommand,TRUE);
  147.             break;
  148.         case ExpCommand:
  149.             CheckItem(mymenu2,ExpCommand,TRUE);
  150.             break;
  151.         case AniCommand:
  152.             CheckItem(mymenu2,AniCommand,TRUE);
  153.             break;
  154.         case TolExpCommand:
  155.             CheckItem(mymenu2,TolExpCommand,TRUE);
  156.             break;
  157.         case TolAniCommand:
  158.             CheckItem(mymenu2,TolAniCommand,TRUE);
  159.             break;
  160.         case ExpAniCommand:
  161.             CheckItem(mymenu2,ExpAniCommand,TRUE);
  162.             break;
  163.         case TEACommand:
  164.             CheckItem(mymenu2,TEACommand,TRUE);
  165.             break;
  166.         defalut:
  167.             break;
  168.         }
  169. }
  170.  
  171. /*______________________________________________________*/
  172. /*                     Start Sound                      */
  173. /*______________________________________________________*/
  174. void SoundSetUp()
  175. {
  176.     int                i;
  177.     OSErr            err;
  178.     
  179.     chan = nil;
  180.     err = SndNewChannel (&chan, sampledSynth, 0, nil);
  181.     if (err != noErr)
  182.         Debugger();
  183.     
  184.     Head = (SoundHeaderPtr) NewPtrClear (sizeof(SoundHeader));
  185.     Head->samplePtr = *SoundData;
  186.     Head->length = 45838;
  187.     Head->sampleRate = 0x56EE8BA3;        //recorded at 22KHz
  188.     Head->loopStart = 0;
  189.     Head->loopEnd = 0;
  190.     Head->encode = 0;
  191.     Head->baseFrequency = 60;
  192.     Head->sampleArea[0] = 0;
  193.  
  194.     myVars.bytesTotal = Head->length;
  195.     myVars.bytesCopied = 0;
  196.     myVars.dataPtr = Head->samplePtr;
  197.  
  198.     doubleHeader.dbhNumChannels = 1;
  199.     doubleHeader.dbhSampleSize = 8;
  200.     doubleHeader.dbhCompressionID = 0;
  201.     doubleHeader.dbhPacketSize = 0;
  202.     doubleHeader.dbhSampleRate = Head->sampleRate;
  203.     doubleHeader.dbhDoubleBack = (SndDoubleBackProcPtr) &MyDoubleBackProc;
  204.  
  205.     for (i = 0; i <= 1; ++i) {
  206.         doubleBuffer = (SndDoubleBufferPtr) NewPtrClear (sizeof(SndDoubleBuffer) + kDoubleBufferSize);
  207.     
  208.         if (doubleBuffer == nil || MemError() != 0)
  209.             Debugger();
  210.         
  211.         doubleBuffer->dbNumFrames = 0;
  212.         doubleBuffer->dbFlags = 0;
  213.         doubleBuffer->dbUserInfo [0] = (long) &myVars;
  214.     
  215.         MyDoubleBackProc (chan, doubleBuffer);            // initialize the buffers
  216.     
  217.         doubleHeader.dbhBufferPtr [i] = doubleBuffer;
  218.         }
  219. }
  220.  
  221. /*______________________________________________________*/
  222. /*                     Start Sound                      */
  223. /*______________________________________________________*/
  224. void SoundOff()
  225. {
  226.     OSErr        err;
  227.     
  228.     err = SndPlayDoubleBuffer (chan, &doubleHeader);
  229.     if (err != noErr)
  230.         Debugger();
  231. }
  232.  
  233. /*______________________________________________________*/
  234. /*             Set Up Usage of Palette                  */
  235. /*______________________________________________________*/
  236. void Draw()
  237. {
  238.     RGBColor        black = {0,0,0}, White = {65535,65535,65535};
  239.         
  240.     RGBForeColor (&black);
  241.     RGBBackColor (&White);
  242.     CopyBits ((BitMap *) *offscreenGWorld->portPixMap, &myWindow->portBits, 
  243.                     &InitWindowSize, &WinMinusScroll, srcCopy, nil);
  244. }
  245.  
  246. /*______________________________________________________*/
  247. /*             Set Up Usage of Palette                  */
  248. /*______________________________________________________*/
  249. void SetInhibited(int Usage)
  250. /* When the usage of the palette changes I need to rebuild the palette,
  251. so I call this routine.  I need to call SetEntryUsage on all of the entries
  252. of the palette, but I want to make sure that if the monitor is set to a bit depth
  253. low than 8 bits that the palette is limited in its colors.  So the first two colors
  254. (not including white) are set to work at all depths except 1 bit mode.  The next 
  255. 12 entries are set to work on all depths except 1 & 2 bit modes.  The rest of 
  256. the colors are set to only work in 8 bit mode.  I have also set the tolerance to
  257. hex 1500.  With this tolerance I will be able to get most of the colors I need 
  258. and those that I don't get exact will be very close. */
  259. {
  260.     int        i;
  261.     
  262.     CTab2Palette (mycolors, srcPalette, Usage, 0x1500);
  263.     for (i = 1; i <= 2; ++i) {
  264.         SetEntryUsage (srcPalette, i, Usage, 0x1500);
  265.         }
  266.     for (i = 3; i <= 14; ++i) {
  267.         SetEntryUsage (srcPalette, i, Usage+pmInhibitG2+pmInhibitC2, 0x1500);
  268.         }
  269.     for (i = 15; i < numcolor; ++i) {
  270.         SetEntryUsage (srcPalette, i, Usage+pmInhibitG2+pmInhibitC2+
  271.                         pmInhibitG4+pmInhibitC4, 0x1500);
  272.         }
  273. }
  274.  
  275. /*______________________________________________________*/
  276. /*                 About Prog Dialog                    */
  277. /*______________________________________________________*/
  278. void showAboutMeDialog()
  279. {
  280.     GrafPtr     savePort;
  281.     DialogPtr    theDialog;
  282.     short        itemHit;
  283.  
  284.     GetPort(&savePort);
  285.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
  286.     SetPort(theDialog);
  287.  
  288.     do {
  289.         ModalDialog(nil, &itemHit);
  290.     } while (itemHit != okButton);
  291.  
  292.     CloseDialog(theDialog);
  293.  
  294.     SetPort(savePort);
  295.     return;
  296. }
  297.  
  298. /*______________________________________________________*/
  299. /*                 Do Menu Function                     */
  300. /*______________________________________________________*/
  301. void doCommand(mResult)
  302.     long    mResult;
  303. {
  304.     int                     theMenu, theItem;
  305.     char                    daName[256];
  306.     GrafPtr                 savePort;
  307.  
  308.     theItem = LoWord(mResult);
  309.     theMenu = HiWord(mResult);
  310.     
  311.     switch (theMenu) {
  312. /*______________________________________________________*/
  313. /*                    Do Apple Menu                     */
  314. /*______________________________________________________*/
  315.         case appleID:
  316.             if (theItem == aboutMeCommand)
  317.                 showAboutMeDialog();
  318.             else {
  319.                 GetItem(mymenu0, theItem, daName);
  320.                 GetPort(&savePort);
  321.                 (void) OpenDeskAcc(daName);
  322.                 SetPort(savePort);
  323.             }
  324.             break;
  325. /*______________________________________________________*/
  326. /*                     Do File Menu                     */
  327. /*______________________________________________________*/
  328.         case fileID:
  329.             switch (theItem) {
  330.                 case quitCommand:
  331.                     DoneFlag = TRUE;
  332.                     break;
  333.                 default:
  334.                     break;
  335.                 }
  336.             break;
  337.  
  338. /*______________________________________________________*/
  339. /*                     Do File Menu                     */
  340. /*______________________________________________________*/
  341.         case PaletteID:
  342.             switch (theItem) {
  343.                 case CourCommand:
  344.                     CheckMenu(CourCommand);
  345.                     SetInhibited(pmCourteous);
  346.                     break;
  347.                 case TolCommand:
  348.                     CheckMenu(TolCommand);
  349.                     SetInhibited(pmTolerant);
  350.                     break;
  351.                 case ExpCommand:
  352.                     CheckMenu(ExpCommand);
  353.                     SetInhibited(pmExplicit);
  354.                     break;
  355.                 case AniCommand:
  356.                     CheckMenu(AniCommand);
  357.                     SetInhibited(pmAnimated);
  358.                     SoundOff();
  359.                     break;
  360.                 case TolExpCommand:
  361.                     CheckMenu(TolExpCommand);
  362.                     SetInhibited(pmTolerant+pmExplicit);
  363.                     break;
  364.                 case TolAniCommand:
  365.                     CheckMenu(TolAniCommand);
  366.                     SetInhibited(pmTolerant+pmAnimated);
  367.                     SoundOff();
  368.                     break;
  369.                 case ExpAniCommand:
  370.                     CheckMenu(ExpAniCommand);
  371.                     SetInhibited(pmAnimated+pmExplicit);
  372.                     SoundOff();
  373.                     break;
  374.                 case TEACommand:
  375.                     CheckMenu(TEACommand);
  376.                     SetInhibited(pmTolerant+pmExplicit+pmAnimated);
  377.                     SoundOff();
  378.                     break;
  379.                 default:
  380.                     break;
  381.                 }
  382.             SetPalette ((WindowPtr) myWindow, srcPalette, TRUE);
  383.             ActivatePalette ((WindowPtr) myWindow);
  384.             break;
  385.         }
  386.     HiliteMenu(0);
  387.     return;
  388. }
  389.  
  390. /*______________________________________________________*/
  391. /*               Initialization traps                   */
  392. /*______________________________________________________*/
  393. void init()
  394. {
  395.     RgnHandle            tempRgn;
  396.     Rect                BaseRect;
  397.     OSErr                err;
  398.     long                QDfeature, OSfeature;
  399.     GDHandle            SaveGD;
  400.     CGrafPtr            SavePort;
  401.     RGBColor            black = {0,0,0}, White = {65535,65535,65535};
  402.  
  403.     UnloadSeg(_DataInit);
  404.     InitGraf(&qd.thePort);
  405.     FlushEvents(everyEvent, 0);
  406.     InitWindows();
  407.     InitDialogs(nil);
  408.     InitCursor();
  409.     
  410.     DoneFlag = FALSE;
  411.     ThePict = GetPicture(PictID);
  412.     if (ThePict == nil)
  413.         DoneFlag = TRUE;
  414.  
  415. /*______________________________________________________*/
  416. /*            Use Gestalt to find 32BQD                 */
  417. /*______________________________________________________*/
  418. if ((GetTrapAddress(Gestalttest) != GetTrapAddress(NoTrap))) {
  419.     err = Gestalt(gestaltQuickdrawVersion, &QDfeature);
  420.     if (err && (QDfeature & 0x0f00) < 0x0200)
  421.         DoneFlag = TRUE;
  422.     err = Gestalt(gestaltSystemVersion, &OSfeature);
  423.     if (err)
  424.         DoneFlag = TRUE;
  425.     if (!DoneFlag && (QDfeature & 0x0f00) != 0x0200 && OSfeature < 0x0605)
  426.         DoneFlag = TRUE;
  427.     }
  428. else
  429.     DoneFlag = TRUE;
  430. /*______________________________________________________*/
  431. /*                     Set Rects                        */
  432. /*______________________________________________________*/
  433. if (DoneFlag == FALSE) {
  434.     SetRect(&BaseRect, 40, 60, 472, 282);
  435.     SetRect(&WinMinusScroll, BaseRect.left-40, BaseRect.top-60, BaseRect.right-60, 
  436.                 BaseRect.bottom - 80);
  437.     SetRect(&InitWindowSize, WinMinusScroll.left, WinMinusScroll.top, 
  438.                             WinMinusScroll.right, WinMinusScroll.bottom);
  439.     tempRgn = GetGrayRgn();
  440.     HLock ((Handle) tempRgn);
  441.     TotalRect = (**tempRgn).rgnBBox;
  442.     SetRect(&minRect, 80, 80, (**tempRgn).rgnBBox.right - 40, 
  443.                 (**tempRgn).rgnBBox.bottom - 40);
  444.     HUnlock ((Handle) tempRgn);
  445.  
  446. /*______________________________________________________*/
  447. /*        Open Window & set Palette & Picture           */
  448. /*______________________________________________________*/
  449.     GetGWorld (&SavePort, &SaveGD);
  450.     mycolors = GetCTable (clutID);
  451.     (*mycolors)->ctFlags |= 0x4000;
  452.  
  453.     myWindow = NewCWindow(nil, &BaseRect, "", TRUE, zoomDocProc, 
  454.                             (WindowPtr) -1, TRUE, 150);
  455.     SetGWorld((CGrafPtr)myWindow, SaveGD);
  456.     DrawGrowIcon (myWindow);
  457.  
  458.     srcPalette = NewPalette (numcolor, mycolors, pmCourteous, 0);
  459.     SetInhibited(pmCourteous);
  460.     SetPalette ((WindowPtr) myWindow, srcPalette, TRUE);
  461.     
  462.     DrawPicture (ThePict, &InitWindowSize);
  463.  
  464.     GetGWorld (&SavePort, &SaveGD);
  465.     err = NewGWorld (&offscreenGWorld, 8, &InitWindowSize, mycolors, nil, nil);
  466.     if (err)
  467.         Debugger();
  468.     SetGWorld (offscreenGWorld, nil);
  469.     EraseRect (&InitWindowSize);
  470.     DrawPicture (ThePict, &InitWindowSize);
  471.     SetGWorld (SavePort, SaveGD);        
  472.  
  473. /*______________________________________________________*/
  474. /*                    Set menus                         */
  475. /*______________________________________________________*/
  476.     mymenu0 = GetMenu(appleID);
  477.     AddResMenu(mymenu0, 'DRVR');
  478.     InsertMenu(mymenu0,0);
  479.     mymenu1 = GetMenu(129);
  480.     InsertMenu(mymenu1,0);
  481.     mymenu2 = GetMenu(130);
  482.     InsertMenu(mymenu2,0);
  483.     DrawMenuBar();
  484.  
  485. /*______________________________________________________*/
  486. /*                  Set Up Sound                        */
  487. /*______________________________________________________*/
  488.  
  489.     SoundData = GetResource ('snd ', 100);
  490.     if (ResError() != noErr || SoundData == nil)
  491.         Debugger();
  492.     HLock (SoundData);
  493.     SoundSetUp();
  494.     }
  495.     
  496.     return;
  497. }
  498.  
  499. main()
  500. {
  501.     char            key;
  502.     Boolean            track;
  503.     long            growResult;
  504.     EventRecord     myEvent;
  505.     WindowPtr        whichWindow;
  506.     int                yieldTime;
  507.     RGBColor        changecolor;
  508.     CTabHandle        StoreCTab;
  509.     short            Usage, Tolerance;
  510.     OSErr            err;
  511. /*______________________________________________________*/
  512. /*                   Main Event loop                    */
  513. /*______________________________________________________*/
  514.     init();
  515.     yieldTime = 0;
  516.     StoreCTab = GetCTable (clutID);
  517.     for ( ;; ) {
  518.         if (DoneFlag) {
  519.             ExitToShell();
  520.             }
  521.             
  522.         /* If the usage is set to animate than animate the colors one step for eash event loop */
  523.         GetEntryUsage(srcPalette, 1, &Usage, &Tolerance);
  524.         Usage &= 0x0004;
  525.         if (Usage == 0x0004) {
  526.             err = SndChannelStatus (chan, sizeof (Stats), &Stats);
  527.             if (err != noErr)
  528.                 Debugger();
  529.             if (!Stats.scChannelBusy) {
  530.                 err = SndDisposeChannel (chan,FALSE);
  531.                 if (err != noErr)
  532.                     Debugger();
  533.         
  534.                 SoundSetUp();
  535.                 SoundOff();
  536.                 }
  537.             GetEntryColor (srcPalette, 1, &changecolor);
  538.             AnimatePalette (myWindow, StoreCTab, 2, 1, numcolor - 2);
  539.             AnimateEntry (myWindow, numcolor - 1, &changecolor);
  540.             Palette2CTab (srcPalette, StoreCTab);
  541.             }
  542.             
  543.         if (WaitNextEvent(everyEvent, &myEvent, yieldTime, nil)) {
  544.             switch (myEvent.what) {
  545.                 case mouseDown:
  546.                     switch (FindWindow(myEvent.where, &whichWindow)) {
  547.                         case inSysWindow:
  548.                             SystemClick(&myEvent, whichWindow);
  549.                             break;
  550.                         case inMenuBar:
  551.                             doCommand(MenuSelect(myEvent.where));
  552.                             break;
  553.                         case inContent:
  554.                             break;
  555.                         case inDrag:
  556.                             DragWindow (whichWindow, myEvent.where, &TotalRect);
  557.                             Draw();
  558.                             DrawGrowIcon (whichWindow);
  559.                             break;
  560.                         case inGrow:
  561.                             growResult = GrowWindow (whichWindow, myEvent.where,
  562.                                                     &minRect);
  563.                             SizeWindow(whichWindow, LoWord(growResult), 
  564.                                     HiWord(growResult), TRUE);
  565.                             EraseRect(&whichWindow->portRect);
  566.                             SetRect(&WinMinusScroll, whichWindow->portRect.left, 
  567.                                     whichWindow->portRect.top, 
  568.                                     whichWindow->portRect.right-20, 
  569.                                     whichWindow->portRect.bottom - 20);
  570.                             Draw();
  571.                             DrawGrowIcon (whichWindow);
  572.                             break;
  573.                         case inGoAway:
  574.                             track = TrackGoAway (whichWindow, myEvent.where);
  575.                             if (track) {
  576.                                 CloseWindow (whichWindow);
  577.                                 DoneFlag = TRUE;
  578.                                 }
  579.                             break;
  580.                         case inZoomIn:
  581.                             track = TrackBox (whichWindow, myEvent.where, inZoomIn);
  582.                             if (track) {
  583.                                 ZoomWindow (whichWindow, inZoomIn, TRUE);
  584.                                 EraseRect(&whichWindow->portRect);
  585.                                 SetRect(&WinMinusScroll, whichWindow->portRect.left, 
  586.                                         whichWindow->portRect.top, 
  587.                                         whichWindow->portRect.right-20, 
  588.                                         whichWindow->portRect.bottom - 20);
  589.                                 Draw();
  590.                                 DrawGrowIcon (whichWindow);
  591.                                 }
  592.                             break;
  593.                         case inZoomOut:
  594.                             track = TrackBox (whichWindow, myEvent.where, inZoomOut);
  595.                             if (track) {
  596.                                 ZoomWindow (whichWindow, inZoomOut, TRUE);
  597.                                 EraseRect(&whichWindow->portRect);
  598.                                 SetRect(&WinMinusScroll, whichWindow->portRect.left, 
  599.                                         whichWindow->portRect.top, 
  600.                                         whichWindow->portRect.right-20, 
  601.                                         whichWindow->portRect.bottom - 20);
  602.                                 Draw();
  603.                                 DrawGrowIcon (whichWindow);
  604.                                 }
  605.                             break;
  606.                         default:
  607.                             break;
  608.                         }
  609.                     break;
  610.                 case keyDown:
  611.                 case autoKey:
  612.                     key = myEvent.message & charCodeMask;
  613.                     if ( myEvent.modifiers & cmdKey )
  614.                         if ( myEvent.what == keyDown )
  615.                             doCommand(MenuKey(key));
  616.                     break;
  617.                 case updateEvt:
  618.                     if ((WindowPtr) myEvent.message == myWindow) {
  619.                         BeginUpdate((WindowPtr) myWindow);
  620.                         EndUpdate((WindowPtr) myWindow);
  621.                         Draw();
  622.                         }
  623.                     break;
  624.                 case diskEvt:
  625.                     break;
  626.                 case activateEvt:
  627.                     break;
  628.                 case app4Evt:
  629.                     if ((myEvent.message << 31) == 0) { /* Suspend */
  630.                         yieldTime = 30;
  631.                         HideWindow((WindowPtr) myWindow);
  632.                         }
  633.                     else { /* Resume */
  634.                         yieldTime = 0;
  635.                         ShowWindow((WindowPtr) myWindow);
  636.                         SetPort((WindowPtr) myWindow);
  637.                         }
  638.                     break;
  639.                 default:
  640.                     break;
  641.                 }
  642.             }
  643.         }
  644. }